/**
 * 
 */
package org.mspring.mlog.web.freemarker.directive.sql.filter;

import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.log4j.Logger;
import org.mspring.platform.utils.StringUtils;
import org.mspring.platform.web.freemarker.DirectiveUtils;

import freemarker.core.Environment;

/**
 * @author Gao Youbo
 * @since 2013-1-4
 * @Description
 * @TODO
 */
@SuppressWarnings({ "unchecked", "rawtypes" })
public class ParameterValidateFilter extends AbstractSQLValidateFilter {

    private static final Logger log = Logger.getLogger(ParameterValidateFilter.class);

    @Override
    public void doFilter(Map params) {
        // TODO Auto-generated method stub
        String sql = (String) params.get(SQLValidateParamNames.PARAM_SQL);
        Environment env = (Environment) params.get(SQLValidateParamNames.ENVIROMENT_NAME);

        try {
            sql = replace(sql, env);
            params.put(SQLValidateParamNames.PARAM_SQL, sql);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        doNextFilter(params);
    }

    public String replace(String sql, Environment env) throws Exception {
        Matcher m = Pattern.compile("@([\\w\\.]+)").matcher(sql);
        while (m.find()) {
            String value = getParamValue(env, m.group(1));
            sql = StringUtils.replace(sql, m.group(), value);
        }
        return sql;
    }

    public String getParamValue(Environment env, String name) throws Exception {
        String value = "";
        Object root = null;
        if (name.indexOf(".") > 0) {
            String rootName = StringUtils.substringBefore(name, ".");
            root = DirectiveUtils.getItem(env, rootName);

            if (root == null) {
                log.warn("[name = " + name + "]Can't found variable from environment.");
                return "";
            }

            String propertyName = StringUtils.substringAfter(name, ".");
            if (root instanceof Collection) {
                Collection coll = (Collection) root;
                Iterator it = coll.iterator();
                while (it.hasNext()) {
                    Object property = it.next();
                    String propertyValue = BeanUtils.getProperty(property, propertyName);
                    value += "'" + propertyValue + "',";
                }
                value = StringUtils.substringBeforeLast(value, ",");
            } else {
                value = BeanUtils.getProperty(root, propertyName);
            }
        } else {
            root = DirectiveUtils.getItem(env, name);
            if (root == null) {
                log.warn("[name = " + name + "]Can't found variable from environment.");
                return "";
            }
            value = "'" + root + "'";
        }

        return value;
    }

}
